﻿using System;

namespace UtilZ.Dotnet.Ex.Communication.Net.Web
{
    /// <summary>
    /// 中间件基类
    /// </summary>
    public partial class ApiMiddleware
    {
        /// <summary>
        /// 映射get
        /// </summary>
        /// <param name="template">url模板</param>
        /// <param name="mapDelegate">匹配url模板的处理委托</param>
        public void MapGet(string template, Delegate mapDelegate)
        {
            this.CheckMapParameter(template, mapDelegate);
            string basesUrl, urlTemplate;
            this.GetBasesUrl(template, out basesUrl, out urlTemplate);
            this.PrimitiveMap(new HttpGetAttribute(urlTemplate), basesUrl, mapDelegate);
        }

        /// <summary>
        /// 映射post
        /// </summary>
        /// <param name="template">url模板</param>
        /// <param name="mapDelegate">匹配url模板的处理委托</param>
        public void MapPost(string template, Delegate mapDelegate)
        {
            this.CheckMapParameter(template, mapDelegate);
            string basesUrl, urlTemplate;
            this.GetBasesUrl(template, out basesUrl, out urlTemplate);
            this.PrimitiveMap(new HttpPostAttribute(urlTemplate), basesUrl, mapDelegate);
        }

        /// <summary>
        /// 映射put
        /// </summary>
        /// <param name="template">url模板</param>
        /// <param name="mapDelegate">匹配url模板的处理委托</param>
        public void MapPut(string template, Delegate mapDelegate)
        {
            this.CheckMapParameter(template, mapDelegate);
            string basesUrl, urlTemplate;
            this.GetBasesUrl(template, out basesUrl, out urlTemplate);
            this.PrimitiveMap(new HttpPutAttribute(urlTemplate), basesUrl, mapDelegate);
        }

        /// <summary>
        /// 映射delete
        /// </summary>
        /// <param name="template">url模板</param>
        /// <param name="mapDelegate">匹配url模板的处理委托</param>
        public void MapDelete(string template, Delegate mapDelegate)
        {
            this.CheckMapParameter(template, mapDelegate);
            string basesUrl, urlTemplate;
            this.GetBasesUrl(template, out basesUrl, out urlTemplate);
            this.PrimitiveMap(new HttpDeleteAttribute(urlTemplate), basesUrl, mapDelegate);
        }

        /// <summary>
        /// 映射Extension
        /// </summary>
        /// <param name="template">url模板</param>
        /// <param name="mapDelegate">匹配url模板的处理委托</param>
        public void MapExtension(string template, Delegate mapDelegate)
        {
            this.CheckMapParameter(template, mapDelegate);
            string basesUrl, urlTemplate;
            this.GetBasesUrl(template, out basesUrl, out urlTemplate);
            this.PrimitiveMap(new HttpExtensionMethodAttribute(urlTemplate), basesUrl, mapDelegate);
        }



   


        private void PrimitiveMap(HttpMethodAbsAttribute methodAttribute, string basesUrl, Delegate mapDelegate)
        {
            //this.MapPost("", new Action(() => { }));
            //this.MapPost("", new Action<int, string, int>((a, b, c) => { }));
            var apiMethod = new ApiMethod(this._serializer, basesUrl, mapDelegate, methodAttribute);

            //根据url类型当回到相应的集合中
            this.AddApiMethod(apiMethod);
        }




        private void GetBasesUrl(string template, out string basesUrl, out string urlTemplate)
        {
            int leftBraceIndex = template.IndexOf('{');
            int questionIndex = template.IndexOf('?');

            if (leftBraceIndex < 0)
            {
                if (questionIndex < 0)
                {
                    basesUrl = string.Empty;
                    urlTemplate = template;
                }
                else
                {
                    basesUrl = template.Substring(0, questionIndex);
                    urlTemplate = template.Substring(questionIndex + 1);
                }
            }
            else
            {
                if (questionIndex < 0)
                {
                    basesUrl = template.Substring(0, leftBraceIndex);
                    urlTemplate = template.Substring(leftBraceIndex + 1);
                }
                else
                {
                    if (leftBraceIndex < questionIndex)
                    {
                        basesUrl = template.Substring(0, leftBraceIndex);
                        urlTemplate = template.Substring(leftBraceIndex + 1);
                    }
                    else
                    {
                        basesUrl = template.Substring(0, questionIndex);
                        urlTemplate = template.Substring(questionIndex + 1);
                    }
                }
            }
        }

        private void CheckMapParameter(string template, Delegate mapDelegate)
        {
            if (string.IsNullOrWhiteSpace(template))
            {
                throw new ArgumentNullException(nameof(template));
            }

            if (mapDelegate == null)
            {
                throw new ArgumentNullException(nameof(mapDelegate));
            }
        }
    }
}
